/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.blog.city.checkthedep.managedbeans;

import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.ArchivePaths;
import javax.inject.Inject;
import org.junit.Assert;
import java.io.File;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.Archive;
import org.jboss.arquillian.container.test.api.Deployment;
import javax.ejb.EJB;
import com.blog.city.checkthedep.entities.Article;
import com.blog.city.checkthedep.entities.Category;
import com.blog.city.checkthedep.entities.Comment;
import com.blog.city.checkthedep.entities.RegisteredUser;
import com.blog.city.checkthedep.sessionbeans.ArticleFacadeLocal;
import com.blog.city.checkthedep.sessionbeans.CategoryFacadeLocal;
import com.blog.city.checkthedep.sessionbeans.CommentFacadeLocal;
import com.blog.city.checkthedep.sessionbeans.RegisteredUserFacadeLocal;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import org.jboss.arquillian.junit.Arquillian;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 *
 * @author Breath
 * After and Before class fail to initialize and delete the data. Keep taking NullPointerException
 * If you want to run this test you need to rename it so it either ends or starts with test.
 */
 
@RunWith(Arquillian.class)
public class ArticleBeanWithBeforeAndAfterClass {

    /*
     *Information for creating registered users that are need in order to create an article 
     */
    private static final String ARQUILLIAN_NAME = "ARQUILLIAN_TESTER";
    private static final String ARQUILLIAN_SURNAME = "ARQUILLIAN_SURNAME";
    private static final String ARQUILLIAN_USERNAME = "ARQUILLIAN_TESTER";
    private static final String ARQUILLIAN_PASSWORD = "ARQUILLIAN_PASSWORD_";
    private static final String ARQUILLIAN_STREETNAME = "ARQUILLIAN_STREETNAME";
    private static final Integer ARQUILLIAN_ZIP = 55131;
    private static final String ARQUILLIAN_USERTYPE = "student";
    private static final String ARQUILLIAN_EMAIL = "tester@ARQUILLIAN.com";
    private static final String ARQUILLIAN_WEBSITE = "www.testingtesters.com/ARQUILLIAN";
    /*
     * Information for creating articles
     */
    private static final String ARQUILLIAN_STATUS = "draft";
    private static final Date ARQUILLIAN_DATE = new Date(2011, 11, 22);
    private static final String ARQUILLIAN_TITLE = "ARQUILLIAN";
    private static final String ARQUILLIAN_ARTICLE_BODY = "ARQUILLIAN_BODY";
    private static final String ARQUILLIAN_CAT_NAME = "ARQUILLIAN_CATEGORY";
    private static List<Article> articlesForTest = new LinkedList<Article>();
    private static List<Category> catList = new LinkedList<Category>();
    /*
     * Information for EJBs
     */
    @EJB(mappedName = "java:app/test/ArticleFacade!com.blog.city.checkthedep.sessionbeans.ArticleFacadeLocal")
    private static ArticleFacadeLocal articleFac;
    @EJB(mappedName = "java:app/test/RegisteredUserFacade!com.blog.city.checkthedep.sessionbeans.RegisteredUserFacadeLocal")
    private static RegisteredUserFacadeLocal regFac;
    @EJB(mappedName = "java:app/test/CategoryFacade!com.blog.city.checkthedep.sessionbeans.CategoryFacadeLocal")
    private static CategoryFacadeLocal catFac;
    @EJB(mappedName = "java:app/test/CommentFacade!com.blog.city.checkthedep.sessionbeans.CommentFacadeLocal")
    private static CommentFacadeLocal commFac;
    private static List<Article> availableArticles = new LinkedList<Article>();
    private static List<Article> returnDeletedArticles = new LinkedList<Article>();
    private static List<Comment> availableComments = new LinkedList<Comment>();
    private static List<Comment> returnDeletedComments = new LinkedList<Comment>();
    private static List<RegisteredUser> returnDeletedUsers = new LinkedList<RegisteredUser>();
    private static List<RegisteredUser> allAvailableUsers = new LinkedList<RegisteredUser>();
    private static List<RegisteredUser> allTestUsers = new LinkedList<RegisteredUser>();
    private static RegisteredUser regUser = new RegisteredUser();
    private static List<Category> allCategories = new LinkedList<Category>();
    private static List<Category> returnCategories = new LinkedList<Category>();

    /**
     * 
     * @return
     */
    @Deployment
    public static Archive<?> prepareDeployment() {
        WebArchive archive = ShrinkWrap.create(WebArchive.class, "test.war").
                addAsWebResource(new File("src/test/resources/persistenceForArquillian/persistence.xml"), "WEB-INF/classes/META-INF/persistence.xml").
                addPackage("com.blog.city.checkthedep.sessionbeans").
                addPackage("com.blog.city.checkthedep.entities").
                addPackage("com.blog.city.checkthedep.managedbeans").
                addAsWebInfResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"));

        System.out.println(archive.toString(true));
        return archive;
    }


    
    /**
     * 
     */
    @BeforeClass
    public static void setUp(){
        secureComments();
        secureArticles();
        secureRegisteredUsers();
        secureCategories();
        createTestUser();
        createTestCategory();
        createTestArticles();
    }
    
    /**
     * 
     */
    @AfterClass
    public static void tearDown(){
        for (int i = 0; i < articlesForTest.size(); i++) {
            articleFac.remove(articlesForTest.get(i));
        }

        if (catFac.findAll() != null) {
            for (int i = 0; i < catFac.findAll().size(); i++) {
                catFac.remove(catFac.findAll().get(i));
            }
        }

        regFac.remove(regUser);

        for (int i = 0; i < returnDeletedUsers.size(); i++) {
            regFac.edit(returnDeletedUsers.get(i));
            for (int j = 0; j < returnDeletedArticles.size(); j++) {
                if (returnDeletedArticles.get(j).getRegisteredUserId().getUsername().equals(regFac.findAll().get(i).getUsername())) {
                    returnDeletedArticles.get(j).setRegisteredUserId(regFac.findAll().get(i));
                    articleFac.edit(returnDeletedArticles.get(j));
                    for (int k = 0; k < returnDeletedComments.size(); k++) {
                        if (articleFac.findAll().get(j).getTitle().equals(returnDeletedComments.get(k).getArticleId().getTitle())) {
                            returnDeletedComments.get(k).setArticleId(articleFac.findAll().get(j));
                            returnDeletedComments.get(k).setRegisteredUserId(regFac.findAll().get(i));
                            commFac.edit(returnDeletedComments.get(k));
                        }
                    }
                }
            }
        }
    }
    
    private static void secureComments() {
        availableComments = commFac.findAll();
        for (int i = 0; i < availableComments.size(); i++) {
            returnDeletedComments.add(availableComments.get(i));
            commFac.remove(availableComments.get(i));
        }
    }

    private static void secureArticles() {
        availableArticles = articleFac.findAll();
        for (int i = 0; i < availableArticles.size(); i++) {
            returnDeletedArticles.add(availableArticles.get(i));
            articleFac.remove(availableArticles.get(i));
        }
    }

    private static void secureRegisteredUsers() {
        allAvailableUsers = regFac.findAll();
        for (int i = 0; i < allAvailableUsers.size(); i++) {
            returnDeletedUsers.add(allAvailableUsers.get(i));
            regFac.remove(allAvailableUsers.get(i));
        }
    }

    private static void secureCategories() {
        allCategories = catFac.findAll();
        for (int i = 0; i < allCategories.size(); i++) {
            returnCategories.add(allCategories.get(i));
            catFac.remove(allCategories.get(i));
        }
    }

    private static void createTestUser() {
        regUser.setName(ARQUILLIAN_NAME);
        regUser.setSurname(ARQUILLIAN_SURNAME);
        regUser.setUsername(ARQUILLIAN_USERNAME);
        regUser.setPassword(ARQUILLIAN_PASSWORD);
        regUser.setStreetName(ARQUILLIAN_STREETNAME);
        regUser.setZip(ARQUILLIAN_ZIP);
        regUser.setUserType(ARQUILLIAN_USERTYPE);
        regUser.setEmail(ARQUILLIAN_EMAIL);
        regUser.setWebsite(ARQUILLIAN_WEBSITE);
        for (int i = 0; i < 1; i++) {
            allTestUsers.add(i, regUser);
        }
        regFac.create(regUser);
    }

    private static void createTestArticles() {
        for (int i = 0; i < 10; i++) {
            Article article = new Article();
            article.setTitle(ARQUILLIAN_TITLE + i);
            article.setDate(ARQUILLIAN_DATE);
            article.setArticleBody(ARQUILLIAN_ARTICLE_BODY);
            article.setStatus(ARQUILLIAN_STATUS);
            article.setRegisteredUserId(regUser);
            article.setCategoryList(catList);
            articlesForTest.add(i, article);
            articleFac.create(article);
        }
    }

    private static void createTestCategory() {
        Category cat = new Category();
        cat.setName(ARQUILLIAN_CAT_NAME);
        catList.add(0, cat);
        catFac.create(cat);
        cat.setArticleList(articlesForTest);
        catFac.edit(cat);
    }

    /**
     * Test of retrieveArticles method, of class ArticleBean.
     */
    @Test
    public void testRetrieveArticles() {
        List<Article> articleList = articleFac.findAll();
        Assert.assertNotNull(articleList);
        Assert.assertEquals(10, articleList.size());
    }

    /**
     * Test of retrieveOwnArticles method, of class ArticleBean.
     */
    @Test
    public void testRetrieveOwnArticles() {
        List<Article> ownArticlesForTest = new LinkedList<Article>();
        ownArticlesForTest = articleFac.findByRegUserId(regFac.findRegUserByUsername(ARQUILLIAN_USERNAME));
        Assert.assertNotNull(ownArticlesForTest);
        Assert.assertEquals(10, ownArticlesForTest.size());
    }

    /**
     * Test of retrieveLatest method, of class ArticleBean.
     */
    @Test
    public void testRetrieveLatest() {
        List<Article> latestArticles = articleFac.latestArticles();
        Assert.assertEquals(5, latestArticles.size());
    }
}